home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Info-Mac 4
/
Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso
/
Development
/
General
/
DR1.#1 PowerPlant ƒ
/
LPane.cp
< prev
next >
Wrap
Text File
|
1994-02-10
|
31KB
|
1,379 lines
// ===========================================================================
// LPane.cp ©1993 Metrowerks Inc. All rights reserved.
// ===========================================================================
//
// Abstract class for an object that can draw itself and respond to
// mouse clicks
#include "LPane.h"
#include "LView.h"
#include "LStream.h"
const Int16 multiClick_Distance = 4;
// === Static Members ===
LView* LPane::sDefaultView = nil; // Default SuperView for new Panes
LPane* LPane::sLastPaneClicked = nil; // Pane hit by last mouse click
Uint32 LPane::sWhenLastMouseUp = 0;
Uint32 LPane::sWhenLastMouseDown = 0;
Point LPane::sWhereLastMouseDown;
Int16 LPane::sClickCount = 0;
// ---------------------------------------------------------------------------
// • LPane()
// ---------------------------------------------------------------------------
// Default Constructor
LPane::LPane()
{
mPaneID = 0;
mFrameSize.width = mFrameSize.height = 0;
mFrameLocation.h = mFrameLocation.v = 0;
mRefCon = 0;
mFrameBinding.left =
mFrameBinding.top =
mFrameBinding.right =
mFrameBinding.bottom = false;
mSuperView = nil;
mVisible = mActive = mEnabled = triState_Latent;
mLockLevel = 0;
}
// ---------------------------------------------------------------------------
// • LPane(const LPane&)
// ---------------------------------------------------------------------------
// Copy Constructor
LPane::LPane(
const LPane &inOriginal)
{
// Copy members of Original
mPaneID = inOriginal.mPaneID;
mFrameSize = inOriginal.mFrameSize;
mFrameLocation = inOriginal.mFrameLocation;
mFrameBinding = inOriginal.mFrameBinding;
mRefCon = inOriginal.mRefCon;
mSuperView = nil; // Copy is not inside any View
// Pane properties. If Original has
// property ON, Copy is Latent.
mVisible = inOriginal.mVisible;
if (mVisible == triState_On) {
mVisible = triState_Latent;
}
mActive = inOriginal.mActive;
if (mActive == triState_On) {
mActive = triState_Latent;
}
mEnabled = inOriginal.mEnabled;
if (mEnabled == triState_On) {
mEnabled = triState_Latent;
}
mLockLevel = 0;
}
// ---------------------------------------------------------------------------
// • LPane(LStream*)
// ---------------------------------------------------------------------------
// Construct Pane from data in a Stream
LPane::LPane(
LStream *inStream)
{
DataIDT dataID;
inStream->ReadData(&dataID, sizeof(DataIDT));
SignalIf_(dataID != 'Pane');
SPaneInfo paneInfo;
inStream->ReadData(&paneInfo, sizeof(SPaneInfo));
mPaneID = paneInfo.paneID;
mFrameSize.width = paneInfo.width;
mFrameSize.height = paneInfo.height;
mRefCon = paneInfo.refCon;
mVisible = triState_Off;
if (paneInfo.visible) {
mVisible = triState_Latent;
}
mActive = triState_Latent;
mEnabled = triState_Off;
if (paneInfo.enabled) {
mEnabled = triState_Latent;
}
mFrameBinding = paneInfo.bindings;
mLockLevel = 0;
mSuperView = nil;
PutInside(GetDefaultView());
if (mSuperView != nil) {
PlaceInSuperImageAt(paneInfo.leftInSuperImage,
paneInfo.topInSuperImage, false);
}
}
// ---------------------------------------------------------------------------
// • ~LPane
// ---------------------------------------------------------------------------
// Destructor
LPane::~LPane()
{
PutInside(nil);
if (sLastPaneClicked == this) {
sLastPaneClicked = nil;
}
}
// ---------------------------------------------------------------------------
// • FinishCreate
// ---------------------------------------------------------------------------
// Wrapper function for FinishCreateSelf
// You will rarely want to override this function
void
LPane::FinishCreate()
{
FinishCreateSelf();
}
// ---------------------------------------------------------------------------
// • FinishCreateSelf
// ---------------------------------------------------------------------------
// Finish Creating a Pane
//
// This function gets called after creating a Pane from a data stream.
// Override to perform finishing touches that depend on the entire
// Pane hierarchy being constructed.
//
// For example, if a View wants to store a pointer to a SubPane,
// it should override this function to call FindPaneByID for that
// Pane. This saves the overhead of repeatedly calling FindPaneByID
// when the View wants to access that SubPane. You can't do this from
// a Constructor because SubPanes are created after their SuperView.
void
LPane::FinishCreateSelf()
{
}
Boolean
LPane::IsAreaInQDSpace(
Int32 inLeft,
Int32 inTop,
Int16 inWidth,
Int16 inHeight)
{
return ( (inLeft > min_QDCoord) &&
(inTop > min_QDCoord) &&
(inLeft + inWidth < max_QDCoord) &&
(inTop + inHeight < max_QDCoord) );
}
PaneIDT
LPane::GetPaneID() const
{
return mPaneID;
}
void
LPane::SetPaneID(
PaneIDT inPaneID)
{
mPaneID = inPaneID;
}
LPane*
LPane::FindPaneByID(
PaneIDT inPaneID)
{
return (inPaneID == mPaneID) ? this : nil;
}
LView*
LPane::GetDefaultView()
{
return sDefaultView;
}
void
LPane::SetDefaultView(
LView *inView)
{
sDefaultView = inView;
}
GrafPtr
LPane::GetMacPort() const
{
return (mSuperView == nil) ? nil : mSuperView->GetMacPort();
}
Int32
LPane::GetValue() const
{
BreakIfDebug_("GetValue undefined");
return 0;
}
void
LPane::SetValue(
Int32 inValue)
{
BreakIfDebug_("SetValue undefined");
}
StringPtr
LPane::GetDescriptor(
Str255 outDescriptor) const
{
BreakIfDebug_("GetDescriptor undefined");
outDescriptor[0] = 0;
return outDescriptor;
}
void
LPane::SetDescriptor(
ConstStr255Param inDescriptor)
{
BreakIfDebug_("SetDescriptor undefined");
}
Int32
LPane::GetRefCon() const
{
return mRefCon;
}
void
LPane::SetRefCon(
Int32 inRefCon)
{
mRefCon = inRefCon;
}
void
LPane::GetFrameSize(
SDimension16 &outSize) const
{
outSize = mFrameSize;
}
void
LPane::GetFrameLocation(
SPoint32 &outLocation) const
{
outLocation = mFrameLocation;
}
void
LPane::SetFrameBinding(
const SBooleanRect &inFrameBinding)
{
mFrameBinding = inFrameBinding;
}
// ---------------------------------------------------------------------------
// • CalcPortFrameRect
// ---------------------------------------------------------------------------
// Calculate the Pane's Frame Rectangle in Port coordinates
//
// Returns true if the Frame is within QuickDraw space (16-bit)
// Returns false if the Frame is outside QuickDraw space
// and outRect is unchanged
Boolean
LPane::CalcPortFrameRect(
Rect &outRect) const
{
Boolean isInQDSpace =
IsAreaInQDSpace(mFrameLocation.h, mFrameLocation.v,
mFrameSize.width, mFrameSize.height);
if (isInQDSpace) {
outRect.left = mFrameLocation.h;
outRect.top = mFrameLocation.v;
outRect.right = outRect.left + mFrameSize.width;
outRect.bottom = outRect.top + mFrameSize.height;
}
return isInQDSpace;
}
// ---------------------------------------------------------------------------
// • CalcLocalFrameRect
// ---------------------------------------------------------------------------
// Calculate the Pane's Frame Rectangle in local (Image) coordinates
//
// Returns true if the Frame is within QuickDraw space (16-bit)
// Returns false if the Frame is outside QuickDraw space
// and outRect is unchanged
Boolean
LPane::CalcLocalFrameRect(
Rect &outRect) const
{
Boolean isInQDSpace = CalcPortFrameRect(outRect);
if (isInQDSpace) {
PortToLocalPoint(topLeft(outRect));
PortToLocalPoint(botRight(outRect));
}
return isInQDSpace;
}
RgnHandle
LPane::GetLocalUpdateRgn()
{
RgnHandle localUpdateRgnH = nil;
if (mSuperView != nil) {
localUpdateRgnH = mSuperView->GetLocalUpdateRgn();
}
return localUpdateRgnH;
}
// ---------------------------------------------------------------------------
// • ResizeFrameTo
// ---------------------------------------------------------------------------
// Set the dimensions of the Frame
//
// inWidth and inHeight specify the new size in pixels
void
LPane::ResizeFrameTo(
Int16 inWidth,
Int16 inHeight,
Boolean inRefresh)
{
ResizeFrameBy(inWidth - mFrameSize.width,
inHeight - mFrameSize.height,
inRefresh);
}
// ---------------------------------------------------------------------------
// • ResizeFrameBy
// ---------------------------------------------------------------------------
// Change the Frame size by the specified amounts
//
// inWidthDelta and inHeightDelta specify, in pixels, how much larger
// to make the Frame. Positive deltas increase the size, negative deltas
// reduce the size.
void
LPane::ResizeFrameBy(
Int16 inWidthDelta,
Int16 inHeightDelta,
Boolean inRefresh)
{
if (inRefresh) { // Refresh area covered before resize
Refresh();
}
mFrameSize.width += inWidthDelta;
mFrameSize.height += inHeightDelta;
if (inRefresh) { // Refresh area covered after resize
Refresh();
}
// +++ Figure out way to validate area that doesn't need to be
// refreshed. May need a flag. Some Panes do not depend on
// the frame for what they draw; others do.
}
// ---------------------------------------------------------------------------
// • MoveBy
// ---------------------------------------------------------------------------
// Move the location of the Frame by the specified amounts
//
// inHorizDelta and inVertDelta specify, in pixels, how far to move the
// Frame (within its surrounding Image). Positive horiz deltas move to
// the left, negative to the right. Positive vert deltas move down,
// negative up.
void
LPane::MoveBy(
Int32 inHorizDelta,
Int32 inVertDelta,
Boolean inRefresh)
{
if (inRefresh) {
Refresh();
}
mFrameLocation.h += inHorizDelta;
mFrameLocation.v += inVertDelta;
if (inRefresh) {
Refresh();
}
}
// ---------------------------------------------------------------------------
// • PlaceInSuperFrameAt
// ---------------------------------------------------------------------------
// Place the Pane at a location relative to the Frame of its SuperView
//
// inHorizOffset specifies, in pixels, how far the left edge of the
// Frame is from the left edge of its Parent Frame. Positive offsets
// are to the left, negative to the right.
//
// inVertOffset specifies, in pixels, how far the top edge of the
// Frame is from the top edge of its Parent Frame. Positive offsets
// are below, negative above.
void
LPane::PlaceInSuperFrameAt(
Int32 inHorizOffset,
Int32 inVertOffset,
Boolean inRefresh)
{
SignalIf_(mSuperView == nil);
SPoint32 superFrameLoc; // Get location of SuperView's Frame
mSuperView->GetFrameLocation(superFrameLoc);
// Move by difference between new
// and current location
MoveBy(superFrameLoc.h + inHorizOffset - mFrameLocation.h,
superFrameLoc.v + inVertOffset - mFrameLocation.v,
inRefresh);
}
// ---------------------------------------------------------------------------
// • PlaceInSuperImageAt
// ---------------------------------------------------------------------------
// Place the Pane within the Image of its SuperView
//
// inHoriz and inVert specify the distance of the top left of the Frame
// from the top left of the Image of its SuperView
void
LPane::PlaceInSuperImageAt(
Int32 inHorizOffset,
Int32 inVertOffset,
Boolean inRefresh)
{
SignalIf_(mSuperView == nil);
SPoint32 superImageLoc; // Get location of SuperView's Image
mSuperView->GetImageLocation(superImageLoc);
// Move by difference between new
// and current location
MoveBy(superImageLoc.h + inHorizOffset - mFrameLocation.h,
superImageLoc.v + inVertOffset - mFrameLocation.v,
inRefresh);
}
void
LPane::SavePlace(
LStream *outPlace)
{
outPlace->WriteData(&mFrameSize, sizeof(SDimension16));
outPlace->WriteData(&mFrameLocation, sizeof(SPoint32));
}
void
LPane::RestorePlace(
LStream *inPlace)
{
inPlace->ReadData(&mFrameSize, sizeof(SDimension16));
inPlace->ReadData(&mFrameLocation, sizeof(SPoint32));
}
// ---------------------------------------------------------------------------
// • PutInside
// ---------------------------------------------------------------------------
// Put Pane inside the specified View. Location is unspecified.
void
LPane::PutInside(
LView *inView)
{
if (mSuperView != nil) { // Sever ties with old Parent
mSuperView->RemoveSubPane(this);
}
mSuperView = inView;
if (inView != nil) { // Attach to new Parent
inView->AddSubPane(this);
AdaptToNewSurroundings(); // Adjust state to reflect new Parent
}
}
LView*
LPane::GetSuperView()
{
return mSuperView;
}
// ---------------------------------------------------------------------------
// • AdaptToNewSurroundings
// ---------------------------------------------------------------------------
// Adjust state of Pane when installed in a new Parent Pane
void
LPane::AdaptToNewSurroundings()
{
}
// ---------------------------------------------------------------------------
// • AdaptToSuperFrameSize
// ---------------------------------------------------------------------------
// Adjust state of Pane when size of SuperView's Frame changes by the
// specified amounts
void
LPane::AdaptToSuperFrameSize(
Int32 inSurrWidthDelta, // Change in width of SuperView
Int32 inSurrHeightDelta, // Change in height of SuperView
Boolean inRefresh)
{
// When SuperView changes size, a Pane may move or change
// size, depending on how each of its sides is "bound" to
// that of its SuperView. A side that is bound always remains
// the same distance from the corresponding side of its SuperView.
Int32 widthDelta = 0;
Int32 heightDelta = 0;
Int32 horizDelta = 0;
Int32 vertDelta = 0;
if (mFrameBinding.right) {
if (mFrameBinding.left) {
// Both right and left are bound
// Pane resizes horizontally
widthDelta = inSurrWidthDelta;
} else {
// Right bound, left free
// Pane moves horizontally
horizDelta = inSurrWidthDelta;
}
}
if (mFrameBinding.bottom) {
if (mFrameBinding.top) {
// Both bottom and top are bound
// Pane resizes vertically
heightDelta = inSurrHeightDelta;
} else {
// Bottom bound, left free
// Pane moves vertically
vertDelta = inSurrHeightDelta;
}
}
if ( (widthDelta != 0) || (heightDelta != 0) ) {
ResizeFrameBy(widthDelta, heightDelta, inRefresh);
}
if ( (horizDelta != 0) || (vertDelta != 0) ) {
MoveBy(horizDelta, vertDelta, inRefresh);
}
}
// ---------------------------------------------------------------------------
// • AdaptToSuperScroll
// ---------------------------------------------------------------------------
// Adjust state of Pane when its SuperView scrolls by the specified amounts
void
LPane::AdaptToSuperScroll(
Int32 inHorizScroll,
Int32 inVertScroll)
{
Int32 horizDelta = 0;
Int32 vertDelta = 0;
if (!mFrameBinding.left && !mFrameBinding.right) {
// Pane is not bound horizontally
horizDelta = -inHorizScroll; // It moves along with the SuperImage
}
if (!mFrameBinding.top && !mFrameBinding.bottom) {
// Pane is not bound vertically
vertDelta = -inVertScroll; // It moves along with the SuperImage
}
if ( (horizDelta != 0) || (vertDelta != 0) ) {
MoveBy(horizDelta, vertDelta, false);
}
}
// ===========================================================================
// • Mouse Clicks Mouse Clicks •
// ===========================================================================
// ---------------------------------------------------------------------------
// • PointIsInFrame
// ---------------------------------------------------------------------------
// Return whether a Point is inside the Frame of a Pane
//
// inHorizPort and inVertPort are in Port coordinates
Boolean
LPane::PointIsInFrame(
Int32 inHorizPort,
Int32 inVertPort) const
{
return ( (inHorizPort >= mFrameLocation.h) &&
(inHorizPort <= mFrameLocation.h + mFrameSize.width) &&
(inVertPort >= mFrameLocation.v) &&
(inVertPort <= mFrameLocation.v + mFrameSize.height) );
}
// ---------------------------------------------------------------------------
// • IsHitBy
// ---------------------------------------------------------------------------
// Return whether a Pane is hit by the specified point, which is in
// Port coordinates
//
// A Pane is hit if the point is inside its Frame and the Pane is enabled
Boolean
LPane::IsHitBy(
Int32 inHorizPort,
Int32 inVertPort)
{
return (PointIsInFrame(inHorizPort, inVertPort) && IsEnabled());
}
// ---------------------------------------------------------------------------
// • FindSubPaneHitBy
// ---------------------------------------------------------------------------
// Find the SubPane of this Pane that is hit by the specified point.
// Return nil if no SubPane is hit
//
// inHorizPort and inVertPort are in Port coordinates
LPane*
LPane::FindSubPaneHitBy(
Int32 inHorizPort,
Int32 inVertPort)
{
return nil; // A Pane has no SubPanes
}
LPane*
LPane::GetLastPaneClicked()
{
return sLastPaneClicked;
}
Int16
LPane::GetClickCount()
{
return sClickCount;
}
// ---------------------------------------------------------------------------
// • Click
// ---------------------------------------------------------------------------
// Handle a click inside a Pane
void
LPane::Click(
SMouseDownEvent &inMouseDown)
{
if (!inMouseDown.delaySelect) {
PortToLocalPoint(inMouseDown.whereLocal);
UpdateClickCount(inMouseDown);
ClickSelf(inMouseDown);
}
}
// ---------------------------------------------------------------------------
// • ClickSelf
// ---------------------------------------------------------------------------
// Respond to Click inside this Pane
void
LPane::ClickSelf(
const SMouseDownEvent &inMouseDown)
{
}
// ---------------------------------------------------------------------------
// • EventMouseUp
// ---------------------------------------------------------------------------
// Respond to a mouse up event following a click (mouse down) inside a Pane
void
LPane::EventMouseUp(
const EventRecord &inMouseUp)
{
sWhenLastMouseUp = inMouseUp.when; // Needed for multi-click detection
}
// ---------------------------------------------------------------------------
// • UpdateClickCount
// ---------------------------------------------------------------------------
// Determine if the mouse down is part of a multi-click and set internal
// counters
void
LPane::UpdateClickCount(
const SMouseDownEvent &inMouseDown)
{
// Three conditions necessary for a multi-click:
// 1) This is the same Pane as was hit with the last mouse down
// 2) Times of previous and current clicks are close enough
// 3) Locations of previous and current clicks are close enough
if ( (sLastPaneClicked == this) &&
ClickTimesAreClose(inMouseDown.macEvent.when) &&
PointsAreClose(sWhereLastMouseDown, inMouseDown.whereLocal) ) {
sClickCount++;
} else {
sClickCount = 1;
}
// Save info about this click
sLastPaneClicked = this;
sWhereLastMouseDown = inMouseDown.whereLocal;
sWhenLastMouseDown = inMouseDown.macEvent.when;
}
// ---------------------------------------------------------------------------
// • PointsAreClose
// ---------------------------------------------------------------------------
// Return whether the two points are close enough to be part of a
// multi-click. Points are in Local coordinates.
Boolean
LPane::PointsAreClose(
Point inFirstPt,
Point inSecondPt)
{
Int16 hDelta = inFirstPt.h - inSecondPt.h;
if (hDelta < 0) {
hDelta = -hDelta;
}
Int16 vDelta = inFirstPt.v - inSecondPt.v;
if (vDelta < 0) {
vDelta = -vDelta;
}
return ( (hDelta <= multiClick_Distance) &&
(vDelta <= multiClick_Distance) );
}
Boolean
LPane::ClickTimesAreClose(
Uint32 inLastClickTime)
{
return ((inLastClickTime - sWhenLastMouseDown) <= GetDblTime());
}
void
LPane::AdjustCursor(
Point inPortPt,
const EventRecord &inMacEvent)
{
AdjustCursorSelf(inPortPt, inMacEvent);
}
// ---------------------------------------------------------------------------
// • AdjustCursorSelf
// ---------------------------------------------------------------------------
// Set the cursor shape when the cursor is inside a Pane
//
// The input point is in Port coordinates. Use the inMacEvent->modifiers
// if the cursor shape depends on whether modifier keys (such as Option)
// are down.
void
LPane::AdjustCursorSelf(
Point inPortPt,
const EventRecord &inMacEvent)
{
SetCursor(&qd.arrow);
}
Boolean
LPane::IsVisible() const
{
return (mVisible == triState_On);
}
void
LPane::Show()
{
if (mVisible == triState_Off) {
if ((mSuperView != nil) && mSuperView->IsVisible()) {
mVisible = triState_On;
ShowSelf();
} else {
mVisible = triState_Latent;
}
}
}
void
LPane::SuperShow()
{
if (mVisible == triState_Latent) {
mVisible = triState_On;
ShowSelf();
}
}
void
LPane::ShowSelf()
{
Refresh();
}
void
LPane::Hide()
{
Boolean wasVisible = IsVisible();
mVisible = triState_Off;
if (wasVisible) {
HideSelf();
}
}
void
LPane::SuperHide()
{
if (mVisible == triState_On) {
mVisible = triState_Latent;
HideSelf();
}
}
void
LPane::HideSelf()
{
Rect frame; // Force redraw of area covered by Pane
if (CalcPortFrameRect(frame)) { // Don't call Refresh(), which works
InvalPortRect(&frame); // only if Pane is visible.
}
}
Boolean
LPane::IsActive() const
{
return ((mActive == triState_On) && IsVisible());
}
void
LPane::Activate()
{
if (mActive == triState_Off) {
if ((mSuperView != nil) && mSuperView->IsActive()) {
mActive = triState_On;
if (IsActive()) {
ActivateSelf();
}
} else {
mActive = triState_Latent;
}
}
}
void
LPane::SuperActivate()
{
if (mActive == triState_Latent) {
mActive = triState_On;
if (IsActive()) {
ActivateSelf();
}
}
}
void
LPane::ActivateSelf()
{
}
void
LPane::Deactivate()
{
Boolean wasActive = IsActive();
mActive = triState_Off;
if (wasActive) {
DeactivateSelf();
}
}
void
LPane::SuperDeactivate()
{
if (mActive == triState_On) {
Boolean wasActive = IsActive();
mActive = triState_Latent;
if (wasActive) {
DeactivateSelf();
}
}
}
void
LPane::DeactivateSelf()
{
}
Boolean
LPane::IsEnabled() const
{
return ((mEnabled == triState_On) && IsVisible());
}
// ---------------------------------------------------------------------------
// • Enable
// ---------------------------------------------------------------------------
// Enable a Pane
void
LPane::Enable()
{
if (mEnabled == triState_Off) {
if ((mSuperView != nil) && mSuperView->IsEnabled()) {
mEnabled = triState_On;
if (IsEnabled()) {
EnableSelf();
}
} else {
mEnabled = triState_Latent;
}
}
}
void
LPane::SuperEnable()
{
if (mEnabled == triState_Latent) {
mEnabled = triState_On;
if (IsEnabled()) {
EnableSelf();
}
}
}
void
LPane::EnableSelf()
{
}
// ---------------------------------------------------------------------------
// • Disable
// ---------------------------------------------------------------------------
// Disable a Pane
void
LPane::Disable()
{
Boolean wasEnabled = IsEnabled();
mEnabled = triState_Off;
if (wasEnabled) {
DisableSelf();
}
}
void
LPane::SuperDisable()
{
if (mEnabled == triState_On) {
Boolean wasEnabled = IsEnabled();
mEnabled = triState_Latent;
if (wasEnabled) {
DisableSelf();
}
}
}
void
LPane::DisableSelf()
{
}
void
LPane::LockDrawing()
{
mLockLevel--;
}
void
LPane::UnlockDrawing()
{
mLockLevel++;
}
void
LPane::Refresh()
{
Rect frame;
if (IsVisible() && CalcPortFrameRect(frame)) {
InvalPortRect(&frame);
}
}
// ===========================================================================
// • Invalidate/Validate Invalidate/Validate •
// ===========================================================================
// All rectangles and regions must be in Port coordinates
//
// You should use these routines rather than the Toolbox traps InvalRect,
// InvalRgn, ValidRect, and ValidRgn. Those traps require that the current
// GrafPort be a Window. However, a Pane could be in another kind of
// GrafPort, such as a Printer Port or GWorld, where calling one of those
// traps would cause a horrible crash (when the Toolbox tries to access
// a nonexistant update region).
void
LPane::InvalPortRect(
const Rect *inRect)
{
if (mSuperView != nil) {
mSuperView->InvalPortRect(inRect);
}
}
void
LPane::InvalPortRgn(
RgnHandle inRgnH)
{
if (mSuperView != nil) {
mSuperView->InvalPortRgn(inRgnH);
}
}
void
LPane::ValidPortRect(
const Rect *inRect)
{
if (mSuperView != nil) {
mSuperView->ValidPortRect(inRect);
}
}
void
LPane::ValidPortRgn(
RgnHandle inRgnH)
{
if (mSuperView != nil) {
mSuperView->ValidPortRgn(inRgnH);
}
}
// ---------------------------------------------------------------------------
// • UpdatePort
// ---------------------------------------------------------------------------
// Redraw invalidated area of the Port containing the Pane
//
// For Panes that are in a Window Port (i.e., the ultimate super view
// is a Window), this forces an immediate redraw of the update region
// of the Window. Since this message is really directed at the Port
// containing the Pane (rather than the Pane itself), the update occurs
// even if the Pane is not visible.
//
// Panes that maintain a Mac GrafPort must override this function if
// they support updating.
void
LPane::UpdatePort()
{
if (mSuperView != nil) {
mSuperView->UpdatePort();
}
}
// ---------------------------------------------------------------------------
// • FocusDraw
// ---------------------------------------------------------------------------
// Prepare for drawing in the Pane
//
// Returns true if the Pane is focused
// Returns false if the Pane could not be focused
//
// A Pane does not have its own coordinate system and clipping region.
// It relies on its SuperView to set the focus.
Boolean
LPane::FocusDraw()
{
return ( (mLockLevel >= 0) &&
((mSuperView == nil) || mSuperView->FocusDraw()) );
}
// ---------------------------------------------------------------------------
// • Draw
// ---------------------------------------------------------------------------
// Try to draw contents of a Pane
//
// inSuperDrawRgnH specifies, in Port coordinates, the portion of the
// Pane's SuperView that needs to be drawn. Specify nil to bypass
// the intersection test.
//
// This is a wrapper function which calls DrawSelf if it is proper for
// the Pane to draw. This means that:
// > Pane's Visible property is on
// > Pane can be focused
// > Pane's Frame is in QuickDraw space
// > Pane's Frame intersects inSuperDrawRgnH
void
LPane::Draw(
RgnHandle inSuperDrawRgnH)
{
Rect frame;
if ( IsVisible() &&
FocusDraw() &&
CalcPortFrameRect(frame) &&
((inSuperDrawRgnH == nil) || RectInRgn(&frame, inSuperDrawRgnH)) ) {
DrawSelf();
}
}
// ---------------------------------------------------------------------------
// • DrawSelf
// ---------------------------------------------------------------------------
// Draw contents of Pane
//
// Derived classes must override this function in order to draw. Normally,
// you will call CalcLocalFrameRect to get a QuickDraw rectangle defining
// the size and location of the Pane. Perform all drawing operations
// relative to the frame rectangle. For example:
//
// PenNormal();
// Rect frame;
// CalcLocalFrameRect(frame);
// FrameRect(&frame);
// MoveTo(frame.left, frame.top);
// LineTo(frame.right, frame.bottom);
//
// This draws a box around the Pane and a diagonal line from
// the top left to the bottom right corner.
//
// Clipping:
// On entry, the clipping region is the revealed area of the Pane's
// SuperView. Therefore, it is possible for a Pane to draw outside of
// its Frame. You will not normally do this.
//
// Usage Note: The port, coordinate system, and clipping region are
// set on entry. They must be the same upon exit. You are responsible
// for setting the Pen state and text characteristics to the proper
// values for your Pane.
void
LPane::DrawSelf()
{
}
// ---------------------------------------------------------------------------
// • CountPanels
// ---------------------------------------------------------------------------
// Return the number of horizontal and vertical Panels. A Panel is a
// "frameful" of a Pane.
void
LPane::CountPanels(
Uint32 &outHorizPanels,
Uint32 &outVertPanels)
{
outHorizPanels = 1; // A Pane is the same size as its
outVertPanels = 1; // Frame, so there's only one Panel
}
// ---------------------------------------------------------------------------
// • PrintPanel
// ---------------------------------------------------------------------------
// Try to Print a Panel of a Pane
void
LPane::PrintPanel(
const PanelSpec &inPanel,
RgnHandle inSuperPrintRgnH)
{
Rect frame;
if ( IsVisible() &&
FocusDraw() &&
CalcPortFrameRect(frame) &&
((inSuperPrintRgnH == nil) ||
RectInRgn(&frame, inSuperPrintRgnH)) ) {
PrintPanelSelf(inPanel);
}
}
// ---------------------------------------------------------------------------
// • SuperPrintPanel
// ---------------------------------------------------------------------------
// SuperView is printing a panel
void
LPane::SuperPrintPanel(
const PanelSpec &inSuperPanel,
RgnHandle inSuperPrintRgnH)
{
PrintPanel(inSuperPanel, inSuperPrintRgnH);
}
// ---------------------------------------------------------------------------
// • PrintPanelSelf
// ---------------------------------------------------------------------------
// Print a Panel of a Pane
void
LPane::PrintPanelSelf(
const PanelSpec &inPanel)
{
DrawSelf();
}
// ---------------------------------------------------------------------------
// • PortToLocalPoint
// ---------------------------------------------------------------------------
// Convert point from Port to Local coordinates
void
LPane::PortToLocalPoint(
Point &ioPoint) const
{
if (mSuperView != nil) {
mSuperView->PortToLocalPoint(ioPoint);
}
}
// ---------------------------------------------------------------------------
// • LocalToPortPoint
// ---------------------------------------------------------------------------
// Convert point from Local to Port coordinates
void
LPane::LocalToPortPoint(
Point &ioPoint) const
{
if (mSuperView != nil) {
mSuperView->LocalToPortPoint(ioPoint);
}
}
void
LPane::GlobalToPortPoint(
Point &ioPoint) const
{
if (mSuperView != nil) {
mSuperView->GlobalToPortPoint(ioPoint);
}
}
void
LPane::PortToGlobalPoint(
Point &ioPoint) const
{
if (mSuperView != nil) {
mSuperView->PortToGlobalPoint(ioPoint);
}
}